package com.example.demo.zhxy;

import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.MapSort;
import com.example.demo.zhxy.SignKit.ZhxyApp;
import com.example.demo.zhxy.entity.ObjectInfo;
import com.example.demo.zhxy.entity.SendMsgEntity;
import com.jeeplus.common.utils.CommonUtil;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.text.UnicodeUtil;
import cn.hutool.crypto.SecureUtil;
import jodd.bean.BeanTemplateParser;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.val;
import lombok.extern.slf4j.Slf4j;

@Data
@Slf4j
@AllArgsConstructor
public class ZhxyRestApi {

	private ZhxyApp app;
	private final String urlBase = "https://open.campus.qq.com/api";

	/**
	 * 根据用户类型获取组织架构列表
	 * 
	 * @param usertype 角色类型（1-学生；2-教师；3-家长；4-校友；5-退休教师 )
	 * @return {"code":0,"msg":"成功","datetime":"40.0830078125
	 *         ms","data":[{"parentid":"NUcsmoPOS5gdone","level":"1","departid":"Z4TaabXqxmasvcdone","departname":"学生","departcode":"","child":[{"parentid":"Z4TaabXqxmasvcdone","level":"4","departid":"DtQNEjuneEtf6Edone","departname":"会计系","departcode":"hjx201631","child":[{"parentid":"DtQNEjuneEtf6Edone","level":"6","departid":"gibH1n3w7Ksdone","departname":"16会计1班","departcode":"1019_1491536825273_158921"}]},{"parentid":"Z4TaabXqxmasvcdone","level":"4","departid":"AEWvL0xmashSwAdone","departname":"计算机系","departcode":"jsjx201522","child":[{"parentid":"AEWvL0xmashSwAdone","level":"6","departid":"wRxDespFcPYdone","departname":"信计09","departcode":"1019_1494561389523_158923"}]}]}]}
	 *         {"code":0,"msg":"成功","datetime":"33.81201171875
	 *         ms","data":[{"parentid":"NUcsmoPOS5gdone","level":"1","departid":"7xKNPkbIrEQdone","departname":"教师","departcode":"","child":[{"parentid":"7xKNPkbIrEQdone","level":"2","departid":"QBXUxmaszgfGHEdone","departname":"校长室","departcode":"XZS"},{"parentid":"7xKNPkbIrEQdone","level":"2","departid":"IDzXsdsjhMEdone","departname":"副校长室","departcode":"FXZS"},{"parentid":"7xKNPkbIrEQdone","level":"2","departid":"nKUtLSZMB3Idone","departname":"办公室","departcode":"001"},{"parentid":"7xKNPkbIrEQdone","level":"2","departid":"4rust1Y2OyYdone","departname":"教务处","departcode":"002"},{"parentid":"7xKNPkbIrEQdone","level":"2","departid":"FTIlkuOph1Edone","departname":"信息中心","departcode":"305"},{"parentid":"7xKNPkbIrEQdone","level":"2","departid":"l3ELwF9YJnEdone","departname":"财经专业科","departcode":"105"},{"parentid":"7xKNPkbIrEQdone","level":"2","departid":"BdJvxtodpuMdone","departname":"计算机专业科","departcode":"103"},{"parentid":"7xKNPkbIrEQdone","level":"2","departid":"3Ta0lgxVJxmas4done","departname":"语文教研组","departcode":"201"},{"parentid":"7xKNPkbIrEQdone","level":"2","departid":"upIHWNCAFXcdone","departname":"数学教研组","departcode":"202"},{"parentid":"7xKNPkbIrEQdone","level":"2","departid":"TGw9sEN6FXcdone","departname":"英语教研组","departcode":"203"},{"parentid":"7xKNPkbIrEQdone","level":"2","departid":"2xW8Tq9H1vEdone","departname":"体育教研组","departcode":"205"},{"parentid":"7xKNPkbIrEQdone","level":"2","departid":"Hjt8bcVyAfgdone","departname":"政治教研组","departcode":"204"},{"parentid":"7xKNPkbIrEQdone","level":"2","departid":"GjuneAVfn2xOMEdone","departname":"测试组","departcode":"1019_1491809239821_147601"}]}]}
	 */
	public String getDepartmentInfoList(int usertype) {
		String url = urlBase + "/open/getDepartmentInfoList";
		Map<String, Object> parameters = new HashMap<String, Object>();
		parameters.put("usertype", usertype);
		return invokeApiByGet(url, "HTTPS", parameters);
	}

	/**
	 * 获取老师、学生、家长、退休老师、校友等用户列表数据
	 * 
	 * @param usertype 查询角色。（1-学生；2-老师；4-校友；5-退休老师；6-上级单位成员）
	 * @param departid 组织架构ID
	 * @param level    组织架构level。如：6-学生班级
	 * @param          param[0] 分页参数，当前页码
	 * @param          param[1] 分页参数，每页显示记录数
	 * @return {"code":0,"msg":"成功","datetime":"19.89013671875
	 *         ms","data":{"pageInfo":{"total":1,"page":1,"size":30},"dataList":[{"userid":"65OB9n9hvQ4done","user_no":"15521282715","name":"chen","is_subscribe":"0"}]}}
	 */
	public String searchUser(int usertype, String departid, int level, Integer... param) {
		String url = "https://open.campus.qq.com/api/common/searchUser";
		Map<String, Object> parameters = new HashMap<>();
		parameters.put("usertype", usertype);
		parameters.put("departid", departid);
		parameters.put("level", level);
		if (param.length >= 1) {
			parameters.put("page", String.valueOf(param[0]));
		}
		if (param.length >= 2) {
			parameters.put("size", String.valueOf(param[1]));
		}
		return invokeApiByGet(url, "HTTPS", parameters);
	}

	public String invokeApiByGet(String url, String http, Map<String, Object> parameters) {
		String resultUrl = buildUrl(url, "GET", parameters);
		// System.out.println(resultUrl);
		String result = null;
		if (http.toUpperCase().equals("HTTP")) {
			result = CommonUtil.httpRequest(resultUrl, "GET", null).toString();
		} else {
			result = CommonUtil.httpsRequest(resultUrl, "GET", null).toString();
		}
		log.info("result:" + result);
		return result;
	}

	private String buildUrl(String url, String requestMethod, Map<String, Object> parameters) {
		StringBuilder stringBuilder = new StringBuilder(url);

		// 公共参数
		Map<String, Object> commmonParams = new HashMap<>();
		commmonParams.put("timestamp", String.valueOf(new Date().getTime()));
		commmonParams.put("objectid", app.getObjectId());
		commmonParams.put("objType", app.getObjType());
		commmonParams.put("openAppID", app.getOpenAppId());
//		commmonParams.put("devCode", devCode);
//		commmonParams.put("devType", devType);
		commmonParams = sortMapByKey(commmonParams);

		String urlParam = null;
		if (requestMethod.toUpperCase().equals("GET")) {
			parameters.putAll(commmonParams);
			urlParam = buildParams(parameters);
		} else {
			// post请求公共参数
			urlParam = buildParams(commmonParams);
			// 参数合并
			parameters.putAll(commmonParams);
			parameters = sortMapByKey(parameters);
		}

		// 获取签名
		String sign = getSign(parameters, app.getAppSecre());
		stringBuilder.append("?").append(urlParam).append("&sign=" + sign);
		log.info("请求URL参数：" + stringBuilder.toString());
		return stringBuilder.toString();
	}

	/**
	 * 签名
	 * 
	 * @param parameters
	 * @param appSecret
	 * @return
	 */
	private static String getSign(Map<String, Object> parameters, String appSecret) {
		String params = buildParams(parameters) + "&key=" + appSecret;
		String sign = SecureUtil.md5(params).toUpperCase();
		return sign;
	}

	/**
	 * 组装参数
	 * 
	 * @param parameters
	 * @return
	 */
	private static String buildParams(Map<String, Object> parameters) {
		// 对参数进行排序
		String[] sortedKeys = (String[]) parameters.keySet().toArray(new String[] {});
		Arrays.sort(sortedKeys);
		StringBuilder result = new StringBuilder();
		for (String key : sortedKeys) {
			result.append("&").append(key).append("=").append(parameters.get(key));
		}
		return result.toString().substring(1);
	}

	public static Map<String, Object> sortMapByKey(Map<String, Object> map) {
		if (map == null || map.isEmpty()) {
			return null;
		}
		Map<String, Object> sortMap = new TreeMap<String, Object>(new MapKeyComparator());
		sortMap.putAll(map);
		return sortMap;
	}

	static class MapKeyComparator implements Comparator<String> {

		@Override
		public int compare(String str1, String str2) {
			return str1.compareTo(str2);
		}
	}

	public void sendMsg(com.example.demo.zhxy.entity.SendMsgEntity.Data data) throws IOException {
		String url = urlBase + "/open/sendMsg";
		long time = System.currentTimeMillis() / 1000;

		SendMsgEntity se = new SendMsgEntity();
		se.setTimestamp(time);
		se.setObjType(app.getObjType());
		se.setOpenAppID(app.getOpenAppId());
		se.setObjectid(app.getObjectId());
		se.setData(data);
		String params = "data[content]=${data.content}&data[msgtype]=${data.msgtype}&data[wxdepartid]=${data.wxdepartid}&data[wxuserid]=${data.wxuserid}&objType=${objType}&objectid=${objectid}&openAppID=${openAppID}&timestamp=${timestamp}";
		params = new BeanTemplateParser().parseWithBean(params, se);
		String sign = SecureUtil.md5(params + "&key=" + app.getAppSecre()).toUpperCase();
		se.setSign(sign);
		String urlFinal = StrFormatter.format("{}?{}&sign={}", url,params,sign);
		HttpRequest post = HttpRequest.post(urlFinal);
		HttpResponse send = post.send();
		
		System.out.println(UnicodeUtil.toString(send.body()));
	}

	/**
	 * 获取学校信息
	 * 
	 * @return
	 */
	public ObjectInfo getObjectInfo() {
		String url = urlBase + "/open/getObjectInfo";
		Map<String, Object> params = new HashMap<>();
		String json = new SignKit(app).get(url, params);
		return JSONObject.parseObject(json, ObjectInfo.class);
	}
}
